package initialize

import (
	"gitee.com/war2001/NiuMaEasyGo/model"
	"gitee.com/war2001/NiuMaEasyGo/nm_core/router"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

// InitMenus 初始化菜单
func InitMenus(registry *router.ControllerRegistry, db *gorm.DB) error {
	// 生成菜单
	zap.L().Info("开始初始化菜单")
	menus := registry.GenerateMenus()
	zap.L().Info("从控制器注册表生成菜单", zap.Int("菜单数量", len(menus)))

	// 检查数据库中是否已存在菜单
	var count int64
	db.Model(&model.SysMenu{}).Count(&count)
	zap.L().Info("数据库中现有菜单数量", zap.Int64("count", count))

	// 如果数据库中没有菜单，或者强制重新创建，则插入生成的菜单
	forceRecreate := len(menus) > 0 && count == 0 // 只有在没有菜单时才创建
	if forceRecreate {
		zap.L().Info("数据库中没有菜单，开始创建菜单")
		// 先创建目录
		var directories []*model.SysMenu
		for _, menu := range menus {
			if menu.Type == "directory" {
				directories = append(directories, menu)
			}
		}

		if len(directories) > 0 {
			if err := db.CreateInBatches(directories, 100).Error; err != nil {
				zap.L().Error("创建目录菜单失败", zap.Error(err))
				return err
			}
		}

		// 创建菜单（需要关联父级）
		var menuItems []*model.SysMenu
		for _, menu := range menus {
			if menu.Type == "menu" {
				// 如果有父级目录，查找父级ID
				if menu.ParentID > 0 {
					var parent model.SysMenu
					if err := db.Where("id = ?", menu.ParentID).First(&parent).Error; err == nil {
						menu.ParentID = uint64(parent.ID)
					}
				}
				menuItems = append(menuItems, menu)
			}
		}

		if len(menuItems) > 0 {
			if err := db.CreateInBatches(menuItems, 100).Error; err != nil {
				zap.L().Error("创建菜单项失败", zap.Error(err))
				return err
			}
		}

		// 创建按钮（需要关联父级）
		var buttons []*model.SysMenu
		for _, menu := range menus {
			if menu.Type == "button" {
				// 如果有父级菜单，查找父级ID
				if menu.ParentID > 0 {
					var parent model.SysMenu
					if err := db.Where("id = ?", menu.ParentID).First(&parent).Error; err == nil {
						menu.ParentID = uint64(parent.ID)
					}
				}
				buttons = append(buttons, menu)
			}
		}

		if len(buttons) > 0 {
			if err := db.CreateInBatches(buttons, 100).Error; err != nil {
				zap.L().Error("创建按钮失败", zap.Error(err))
				return err
			}
		}

		// 为管理员角色分配所有菜单权限
		var adminRole model.SysRole
		if err := db.Where("code = ?", "admin").First(&adminRole).Error; err == nil {
			// 获取所有菜单ID
			var menuIDs []uint64
			db.Model(&model.SysMenu{}).Pluck("id", &menuIDs)

			if len(menuIDs) > 0 {
				roleMenus := make([]model.SysRoleMenu, 0, len(menuIDs))
				for _, menuID := range menuIDs {
					roleMenus = append(roleMenus, model.SysRoleMenu{
						RoleID: uint64(adminRole.ID),
						MenuID: menuID,
					})
				}

				if err := db.CreateInBatches(roleMenus, 100).Error; err != nil {
					zap.L().Error("为管理员分配菜单权限失败", zap.Error(err))
					return err
				}
			}
		}

		zap.L().Info("菜单初始化成功", zap.Int("count", len(menus)))
	} else {
		zap.L().Info("菜单已存在，跳过创建，但检查权限分配")
	}

	// 确保管理员角色有所有菜单权限（无论菜单是否重新创建）
	var adminRole model.SysRole
	if err := db.Where("code = ?", "admin").First(&adminRole).Error; err == nil {
		zap.L().Info("找到管理员角色",
			zap.Uint("roleID", adminRole.ID),
			zap.String("roleName", adminRole.Name),
			zap.String("roleCode", adminRole.Code))
		// 检查是否已经有权限分配
		var roleMenuCount int64
		db.Model(&model.SysRoleMenu{}).Where("role_id = ?", adminRole.ID).Count(&roleMenuCount)

		if roleMenuCount == 0 {
			zap.L().Info("管理员角色没有菜单权限，开始分配")
			// 获取所有菜单ID
			var menuIDs []uint64
			db.Model(&model.SysMenu{}).Pluck("id", &menuIDs)

			if len(menuIDs) > 0 {
				roleMenus := make([]model.SysRoleMenu, 0, len(menuIDs))
				for _, menuID := range menuIDs {
					roleMenus = append(roleMenus, model.SysRoleMenu{
						RoleID: uint64(adminRole.ID),
						MenuID: menuID,
					})
				}

				if err := db.CreateInBatches(roleMenus, 100).Error; err != nil {
					zap.L().Error("为管理员分配菜单权限失败", zap.Error(err))
					return err
				} else {
					zap.L().Info("为管理员分配菜单权限成功", zap.Int("菜单数量", len(menuIDs)))
				}
			}
		} else {
			zap.L().Info("管理员角色已有菜单权限", zap.Int64("权限数量", roleMenuCount))
		}
	} else {
		zap.L().Error("未找到管理员角色", zap.Error(err))
	}

	// 调试：检查所有角色和用户角色关联
	var allRoles []model.SysRole
	db.Find(&allRoles)
	zap.L().Info("数据库中所有角色", zap.Int("角色数量", len(allRoles)))
	for _, role := range allRoles {
		zap.L().Info("角色信息",
			zap.Uint("ID", role.ID),
			zap.String("Name", role.Name),
			zap.String("Code", role.Code))
	}

	var allUserRoles []model.SysUserRole
	db.Find(&allUserRoles)
	zap.L().Info("数据库中所有用户角色关联", zap.Int("关联数量", len(allUserRoles)))
	for _, ur := range allUserRoles {
		zap.L().Info("用户角色关联",
			zap.Uint64("UserID", ur.UserID),
			zap.Uint64("RoleID", ur.RoleID))
	}

	// 修复：确保admin用户(ID=2)与admin角色(ID=1)的关联
	var adminUser model.User
	if err := db.Where("username = ?", "admin").First(&adminUser).Error; err == nil {
		zap.L().Info("找到admin用户", zap.Uint("userID", adminUser.ID))

		var adminRole model.SysRole
		if err := db.Where("code = ?", "admin").First(&adminRole).Error; err == nil {
			// 检查是否已存在用户角色关联
			var existingUserRole model.SysUserRole
			if err := db.Where("user_id = ? AND role_id = ?", adminUser.ID, adminRole.ID).First(&existingUserRole).Error; err != nil {
				// 不存在，创建关联
				userRole := model.SysUserRole{
					UserID: uint64(adminUser.ID),
					RoleID: uint64(adminRole.ID),
				}
				if err := db.Create(&userRole).Error; err != nil {
					zap.L().Error("创建用户角色关联失败", zap.Error(err))
				} else {
					zap.L().Info("成功创建用户角色关联",
						zap.Uint("userID", adminUser.ID),
						zap.Uint("roleID", adminRole.ID))
				}
			} else {
				zap.L().Info("用户角色关联已存在")
			}
		}
	}

	return nil
}
